home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 18 / CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso / CUCD / Online / AList / src / alcmd.e < prev    next >
Encoding:
Text File  |  1997-10-20  |  13.8 KB  |  484 lines

  1. /* ALCmd.M */
  2.  
  3. OPT MODULE
  4. OPT EXPORT
  5.  
  6. /* Module to process commands to the AList mailing list server */
  7.  
  8. MODULE 'other/alconfig'
  9. MODULE 'other/aladd'
  10. MODULE 'other/alpost'
  11.  
  12.  
  13. DEF config_list:PTR TO config_node, hostname:PTR TO CHAR, no_from
  14. /* From aladd.m */
  15. DEF temp_file:PTR TO CHAR
  16. /* From alconfig */
  17. DEF alternate_cmd:PTR TO CHAR
  18.  
  19. /*
  20.  * Perform one or more commands, as specified by the chained string 'str'.
  21.  */
  22. PROC do_command (str:PTR TO CHAR)
  23.    DEF from:PTR TO CHAR, to:PTR TO CHAR, list:PTR TO config_node, tmp:PTR TO config_node, s:PTR TO CHAR
  24.    DEF s2:PTR TO CHAR, x, y
  25.  
  26.    to := str
  27.    list := find_list (to)
  28.    from := str := Next (str)
  29.    str := Next (str)
  30.  
  31.    WHILE (is_empty (str) = FALSE)
  32.       str := Next (str)
  33.    ENDWHILE
  34.  
  35.    IF (str = NIL)  THEN RETURN      /* Don't do a Next (NIL)! */
  36.  
  37.    clear_tmp_file()
  38.    s := String (75)
  39.    IF (no_from OR alternate_cmd)
  40.       StringF (s, 'From:  AList@\s\n\n', hostname)
  41.       add_tmp_file (s)
  42.    ENDIF
  43.  
  44.    WHILE (str := Next (str))
  45.       StrCopy (s, str)
  46.       UpperStr (s)
  47.       IF (StrCmp (s, 'HELP', 4))
  48.          add_tmp_file ('\nResponse to command\n>>')
  49.          add_tmp_file (str)
  50.          add_tmp_file ('\n')
  51.          add_tmp_help (TrimStr (str+4))
  52.       ELSEIF (StrCmp (s, 'INDEX', 5))
  53.          add_tmp_file ('\nResponse to command\n>>INDEX\n\n')
  54.          tmp := config_list
  55.          y := 0
  56.          IF (tmp)  THEN add_tmp_file ('Visible lists:')  ELSE add_tmp_file ('No visible lists.\n\n')
  57.          WHILE (tmp)
  58.             IF (y = 0)  THEN y := 1
  59.             IF ((tmp.flags AND CNF_INVISIBLE) = 0)
  60.                y := 2
  61.                StringF (s, '\n\s[15]\t  \s\n', tmp.name, IF (tmp.sdesc)  THEN tmp.sdesc ELSE '')
  62.                add_tmp_file (s)
  63.                tmp := tmp.next
  64.             ENDIF
  65.          ENDWHILE
  66.          IF (y = 1)  THEN add_tmp_file ('No visible lists.\n\n')
  67.       ELSEIF (StrCmp (s, 'LIST', 4))
  68.          add_tmp_file ('\nResponse to command\n>>')
  69.          add_tmp_file (str)
  70.  
  71.          StrCopy (s, from)
  72.          s2 := TrimStr (str+4)
  73.          y := 0
  74.          IF (IF (s2 = -1)  THEN FALSE ELSE (s2[0] > 32))
  75.             StrCopy (s, s2, StrLen (s2) - 1)
  76.             y := 1
  77.          ENDIF
  78.  
  79.          tmp := config_list;  x := 0
  80.          WHILE (tmp)
  81.             IF ((y = 0) OR ((tmp.flags AND CNF_INVISIBLE) = 0) )
  82.                IF (on_list (s, tmp.users, (tmp.flags AND CNF_CMP_DOMAIN)))
  83.                   x := 1
  84.                   StringF (s, '\s[15]\t  \s\n', tmp.name, IF (tmp.sdesc)  THEN tmp.sdesc ELSE '')
  85.                   add_tmp_file (s)
  86.                ENDIF
  87.             ENDIF
  88.             tmp := tmp.next
  89.          ENDWHILE
  90.  
  91.          IF (x = 0)
  92.             IF (y = 0)
  93.                add_tmp_file ('You are not on any lists at this site.\nYour address is "')
  94.                add_tmp_file (s)
  95.                add_tmp_file ('".\n')
  96.             ELSE
  97.                add_tmp_file (s)
  98.                add_tmp_file (' is not on any visible lists at this site.\n')
  99.             ENDIF
  100.          ENDIF
  101.       ELSEIF (StrCmp (s, 'WHO', 3))
  102.          add_tmp_file ('\nResponse to command\n>>')
  103.          add_tmp_file (str)
  104.  
  105.          StrCopy (s, from)
  106.          IF (InStr (s, '@') = -1) AND (InStr (s, '!') = -1)
  107.             /* localhost */
  108.             StrAdd (s, '@')
  109.             StrAdd (s, hostname)
  110.          ENDIF
  111.  
  112.          IF (str[4] < 33)     /* No list */
  113.             tmp := list
  114.          ELSE
  115.             s2 := String (StrLen (str)-5)
  116.             StrCopy (s2, str+4)
  117.             tmp := find_list (s2)
  118.             DisposeLink (s2)
  119.          ENDIF
  120.          IF (tmp = NIL)
  121.             add_tmp_file ('Requested list not found.\n')
  122.             JUMP do_next_cmd
  123.          ENDIF
  124.  
  125.          IF (tmp.flags AND CNF_MOD_WHO_SELF)
  126.             IF (on_list (s, tmp.users, (tmp.flags AND CNF_CMP_DOMAIN)) = FALSE)
  127.                add_tmp_file ('Only members of that list may obtain a list of subscribed users.\n')
  128.                JUMP do_next_cmd
  129.             ENDIF
  130.          ELSEIF (tmp.flags AND CNF_MOD_WHO_OWN)
  131.             s2 := String (80)
  132.             StrCopy (s2, tmp.owner)
  133.             IF (tmp.flags AND CNF_CMP_DOMAIN)
  134.                domain_only (s2)
  135.                domain_only (s)
  136.             ENDIF
  137.             IF (StrCmp (s, s2) = FALSE)
  138.                add_tmp_file ('Only the owner of that list may obtain a list of subscribed users.\n')
  139.                DisposeLink (s2)
  140.                JUMP do_next_cmd
  141.             ENDIF
  142.             DisposeLink (s2)
  143.          ENDIF
  144.  
  145.          s2 := tmp.users
  146.          add_tmp_file ('Members of list "')
  147.          add_tmp_file (tmp.name)
  148.          add_tmp_file ('":')
  149.          WHILE (s2)
  150.             add_tmp_file ('\n\t')
  151.             add_tmp_file (s2)
  152.             s2 := Next (s2)
  153.          ENDWHILE
  154.          add_tmp_file ('\n')
  155.       ELSEIF (StrCmp (s, 'ADD', 3))
  156.          add_tmp_file ('\nResponse to command\n>>')
  157.          add_tmp_file (str)
  158.  
  159.          StrCopy (s, from)
  160.          s2 := String (16)
  161.          IF (list)  THEN StrCopy (s2, list.name)
  162.          get_cmd_args (str+3, s2, s)
  163.          add_user (s, s2)
  164.          DisposeLink (s2)
  165.       ELSEIF (StrCmp (s, 'DELETE', 6))
  166.          add_tmp_file ('\nResponse to command\n>>')
  167.          add_tmp_file (str)
  168.  
  169.          StrCopy (s, from)
  170.          s2 := String (16)
  171.          IF (list)  THEN StrCopy (s2, list.name)
  172.          get_cmd_args (str+6, s2, s)
  173.          remove_user (s, s2)
  174.          DisposeLink (s2)
  175.       ELSEIF (StrCmp (s, 'SUBSCRIBE', 9))
  176.          add_tmp_file ('\nResponse to command\n>>')
  177.          add_tmp_file (str)
  178.  
  179.          StrCopy (s, from)
  180.          s2 := String (16)
  181.          IF (list)  THEN StrCopy (s2, list.name)
  182.          get_cmd_args (str+9, s2, s)
  183.          add_user (s, s2)
  184.          DisposeLink (s2)
  185.       ELSEIF (StrCmp (s, 'UNSUBSCRIBE', 11))
  186.          add_tmp_file ('\nResponse to command\n>>')
  187.          add_tmp_file (str)
  188.  
  189.          StrCopy (s, from)
  190.          s2 := String (16)
  191.          IF (list)  THEN StrCopy (s2, list.name)
  192.          get_cmd_args (str+11, s2, s)
  193.          remove_user (s, s2)
  194.          DisposeLink (s2)
  195.       ELSEIF (StrCmp (s, 'END', 3))
  196.          add_tmp_file ('\nResponse to command\n>>END\nCommand processing ending.\n\n')
  197.          str := NIL        /* Break the loop! */
  198.       ELSEIF (StrCmp (s, 'INFO', 4))
  199.          add_tmp_file ('\nResponse to command\n>>')
  200.          add_tmp_file (str)
  201.          add_tmp_file ('\n\n')
  202.  
  203.          s2 := NIL
  204.          IF (s[4])
  205.             x := 4
  206.             WHILE (IF s[x]  THEN (s[x] < 33) OR (s[x] > 125)  ELSE FALSE)
  207.                INC x
  208.             ENDWHILE
  209.             IF (s[x])
  210.                s2 := String (StrLen (str+x)-1)
  211.                StrCopy (s2, str+x)
  212.             ENDIF
  213.          ENDIF
  214.          IF (s2 = NIL)
  215.             IF (list)
  216.                tmp := list
  217.             ELSE
  218.                add_tmp_file ('Which list do you want the description of?\n\n')
  219.                JUMP do_next_cmd
  220.             ENDIF
  221.          ELSE
  222.             tmp := config_list
  223.             WHILE (IF (tmp)  THEN (StrCmp (tmp.name, s2) = NIL)  ELSE FALSE)
  224.                tmp:= tmp.next
  225.             ENDWHILE
  226.             DisposeLink (s2)
  227.             IF (tmp = NIL)
  228.                add_tmp_file ('Specified list not found.\n\n')
  229.                JUMP do_next_cmd
  230.             ENDIF
  231.          ENDIF
  232.  
  233.          IF (tmp.ldesc = NIL)
  234.             add_tmp_file ('There is no description associated with that list.\n\n')
  235.          ELSE
  236.             DisposeLink (s2)
  237.             s2 := tmp.ldesc
  238.             WHILE (s2)
  239.                add_tmp_file (s2)
  240.                s2 := Next (s2)
  241.             ENDWHILE
  242.             add_tmp_file ('\n')
  243.          ENDIF
  244.       ELSE
  245.          IF (str[0] > 32)
  246.              add_tmp_file ('\nUnknown command:  ')
  247.              add_tmp_file (str)
  248.          ENDIF
  249.       ENDIF
  250. do_next_cmd:
  251.    ENDWHILE
  252.  
  253.    DisposeLink (s)
  254.    add_tmp_file ('\n')
  255.    s := String (70 + EstrLen (from))
  256.    IF (alternate_cmd)
  257.       DisposeLink (s)
  258.       s := generate_alternate_cmd ('AList', 'AList Mailing List Server', 'Re: Your command(s)', from)
  259.    ELSEIF (no_from)
  260.       StringF (s, '-R "AList Mailing List Server" -s "Re: Your command(s)" -t "\s"', from)
  261.    ELSE
  262.       StringF (s, '-f AList -R "AList Mailing List Server" -s "Re: Your command(s)" -t "\s"', from)
  263.    ENDIF
  264.    send_message (s)
  265.    DisposeLink (s)
  266. ENDPROC
  267.  
  268.  
  269. /*
  270.  * Checks to see if a string contains anything
  271.  */
  272. PROC is_empty (str)
  273.    IF (str = NIL)  THEN RETURN TRUE
  274.    str := TrimStr (str)
  275.    IF (str[0])  THEN RETURN FALSE  ELSE RETURN TRUE
  276. ENDPROC
  277.  
  278.  
  279. /*
  280.  * Returns the address of the first whitespace (<33) in the string, or NIL
  281.  */
  282. PROC find_empty (str:PTR TO CHAR)
  283.    DEF x
  284.  
  285.    IF (str = NIL)  THEN RETURN NIL
  286.    x := 0
  287.    WHILE (str[x] > 32)
  288.       INC x
  289.    ENDWHILE
  290.  
  291.    IF (str[x])  THEN RETURN str+x
  292. ENDPROC NIL
  293.  
  294.  
  295. /*
  296.  * Adds a user to a list.
  297.  */
  298. PROC add_user (name:PTR TO CHAR, listname:PTR TO CHAR)
  299.    DEF s:PTR TO CHAR, list:PTR TO config_node
  300.  
  301.    IF (IF (listname[0])  THEN ((list := find_list (listname)) = NIL)  ELSE TRUE)
  302.       add_tmp_file ('Unknown list "')
  303.       add_tmp_file (listname)
  304.       add_tmp_file ('".\nFor a list of known lists, use the INDEX command.\n')
  305.       RETURN
  306.    ENDIF
  307.  
  308. /* Do all tests for permissions to add this user here */
  309.  
  310.    IF (on_list (name, list.users, (list.flags AND CNF_CMP_DOMAIN)))
  311.       add_tmp_file ('User "')
  312.       add_tmp_file (name)
  313.       add_tmp_file ('" is already subscribed to that list.\n')
  314.       RETURN
  315.    ENDIF
  316.  
  317.    s := String (EstrLen (name))
  318.    StrCopy (s, name)
  319.    list.users := add_link (list.users, s)
  320.    add_tmp_file ('User "')
  321.    add_tmp_file (s)
  322.    add_tmp_file ('" has been added to the list "')
  323.    add_tmp_file (list.name)
  324.    add_tmp_file ('".\n')
  325. /* Should really add a post to the owner as well here */
  326.  
  327. /* Now, write out the file */
  328.    IF (write_user_list (list) = FALSE)
  329.       add_tmp_file ('WARNING:  Unable to write user list!  Inform the owner immediately!\n')
  330.    ELSE
  331.       send_list_welcome (name, list)
  332.    ENDIF
  333. ENDPROC
  334.  
  335.  
  336. /*
  337.  * Send off the welcome message to the new user on the list.
  338.  */
  339. PROC send_list_welcome (name:PTR TO CHAR, list:PTR TO config_node)
  340.    DEF s:PTR TO CHAR, tmp2_file:PTR TO CHAR, tmp_s:PTR TO CHAR
  341.    DEF tmp2_s:PTR TO CHAR
  342.  
  343.    /* Move tmp to tmp2 file */
  344.    tmp2_file := temp_file
  345.    temp_file := String (EstrLen (tmp2_file) + 2)
  346.    StrCopy (temp_file, tmp2_file)
  347.    StrAdd (temp_file, 'a')
  348.    clear_tmp_file()
  349.  
  350.    /* Write List Welcome HERE */
  351.    IF (no_from OR alternate_cmd)
  352.       add_tmp_file ('From:  ')
  353.       add_tmp_file (list.name)
  354.       add_tmp_file ('-list-owner@')
  355.       add_tmp_file (hostname)
  356.       add_tmp_file ('\n\n')
  357.    ENDIF
  358.  
  359.    add_tmp_file ('\nWELCOME!\n\nA message from the AList Email server:\n')
  360.    add_tmp_file ('You may unsubscribe at any time by sending a message to\n AList@')
  361.    add_tmp_file (hostname)
  362.    add_tmp_file ('\nwith a line in the body that reads:\nUNSUBSCRIBE ')
  363.    add_tmp_file (list.name)
  364.    add_tmp_file ('\n\nFor a complete listing of commands the AList server accepts,\n')
  365.    add_tmp_file ('send a message with a line containing only the word HELP.\n\n')
  366.  
  367.    IF (list.welcome)
  368.       /* Tack onto the end */
  369.       add_tmp_file (list.welcome)
  370.    ENDIF
  371.  
  372.    s := String (113 + (2 * EstrLen (list.name)) + EstrLen (name))
  373.    IF (alternate_cmd)
  374.       tmp_s := s
  375.       StringF (tmp_s, '\s-list-owner', list.name)
  376.       tmp2_s := String (EstrLen (list.name) + 31)
  377.       StringF (tmp2_s, 'Welcome to the \s mailing list!', list.name)
  378.       s := generate_alternate_cmd (tmp_s, 'AList Mailing List Server', tmp2_s, name)
  379.       DisposeLink (tmp_s)
  380.       DisposeLink (tmp2_s)
  381.    ELSEIF (no_from)
  382.       StringF (s,
  383.          '-R "AList Mailing List Server" -s "Welcome to the \s mailing list!" -t "\s"',
  384.          list.name, name)
  385.    ELSE
  386.       StringF (s,
  387.          '-f \s-list-owner -R "AList Mailing List Server" -s "Welcome to the \s mailing list!" -t "\s"',
  388.          list.name, list.name, name)
  389.    ENDIF
  390.  
  391.    send_message (s)
  392.    DisposeLink (s)
  393.  
  394.    /* Move tmp2 back to tmp */
  395.    DisposeLink (temp_file)
  396.    temp_file := tmp2_file
  397. ENDPROC
  398.  
  399.  
  400. /*
  401.  * Removes a user from a list
  402.  */
  403. PROC remove_user (name:PTR TO CHAR, listname:PTR TO CHAR)
  404.    DEF s:PTR TO CHAR, list:PTR TO config_node, s2:PTR TO CHAR
  405.  
  406.    IF (IF (listname[0])  THEN ((list := find_list (listname)) = NIL)  ELSE TRUE)
  407.       add_tmp_file ('Unknown list "')
  408.       add_tmp_file (listname)
  409.       add_tmp_file ('".\nFor a list of known lists, use the INDEX command.\n')
  410.       RETURN
  411.    ENDIF
  412.  
  413. /* Do all tests for permissions to remove this user here */
  414.  
  415.    IF ((s := on_list (name, list.users, (list.flags AND CNF_CMP_DOMAIN))) = NIL)
  416.       add_tmp_file ('User "')
  417.       add_tmp_file (name)
  418.       add_tmp_file ('" is not subscribed to that list.\n')
  419.       RETURN
  420.    ENDIF
  421.  
  422.    s2 := list.users
  423.    IF (s2 = s)       /* Whoops, removing the head, special case... */
  424.       list.users := Next(s)
  425.       Link (s, NIL)
  426.       DisposeLink (s)
  427.    ELSE
  428.       /* s will still be on from the users list, so no need for NIL checking */
  429.       WHILE (Next (s2) <> s)     /* Note that we don't need to StrCmp here */
  430.          s2 := Next (s2)
  431.       ENDWHILE
  432.       /* Now, we have the one before it */
  433.       Link (s2, Next(s))
  434.       Link (s, NIL)
  435.       DisposeLink (s)
  436.    ENDIF
  437.  
  438.    add_tmp_file ('User "')
  439.    add_tmp_file (s)
  440.    add_tmp_file ('" has been removed from the list "')
  441.    add_tmp_file (list.name)
  442.    add_tmp_file ('".\n')
  443. /* Should really add a post to the owner as well here */
  444.  
  445. /* Now write out the user list */
  446.    IF (write_user_list (list) = FALSE)
  447.       add_tmp_file ('WARNING:  Unable to write user list!  Inform the owner immediately!\n')
  448.    ENDIF
  449. ENDPROC
  450.  
  451.  
  452. /*
  453.  * Fills the 2 defaults with the arguments, if there.  Otherwise, leaves them be.
  454.  *
  455.  * Requires def1 and def2 to be valid buffers (e strings).
  456.  */
  457. PROC get_cmd_args (str, def1:PTR TO CHAR, def2:PTR TO CHAR)
  458.    DEF x, y
  459.  
  460.    x := 0
  461.    WHILE (str[x] < 33) AND (str[x] > 0)
  462.       INC x
  463.    ENDWHILE
  464.    y := x
  465.    WHILE (str[x] > 32)
  466.       INC x
  467.    ENDWHILE
  468.    IF (x > y)
  469.       StrCopy (def1, str+y, x-y)
  470.       WHILE (str[x] < 33) AND (str[x] > 0)
  471.          INC x
  472.       ENDWHILE
  473.       y := x
  474.       WHILE (str[x] > 32)
  475.          INC x
  476.       ENDWHILE
  477.       IF (x > y)
  478.          StrCopy (def2, str+y, x-y)
  479.       ENDIF
  480.    ENDIF
  481. ENDPROC
  482.  
  483.  
  484.